# -*- coding: UTF-8 -*-

from types import *

from Cheetah.Template import Template 



import os
import glob
import sys
import re
import time
###################################################
from encodings import ascii
from encodings import utf_8
from encodings import gb2312

from Cheetah import DummyTransaction

from utils import mc
from utils import stdout
from utils import config
from database import model_sqlite as model
#from database import model  as model
from mapping import mapmysql

###################################################



import wx
try:
  from features.UI.common import windict
except:
  print "could not import windict"

class CodeGen:  
  
  def __init__(self):
    self.tables = {}
    
    self.dirs = ['action', 'business', 'form', 'orm']
    cfg = config.Config("project.cfg")
    self.base = cfg.getOption('project','base_path')    
    self.template_dir = os.getcwd() +"\\"+ cfg.getOption('project','template_dir')    
    #print self.template_dir
    self.project = cfg.getOption('project','name')
    self.genopts =  cfg.options('generator')
    self.genoptdict = {}
    #print self.genopts
    for option in self.genopts:
      self.genoptdict[option] = cfg.getOption('generator',option)
    
    #print self.genoptdict
      
    self.project_path = self.base+"\\"+self.project
    
    self.src = self.project_path+"\\src"
    self.jsp = self.project_path+"\\jsp"
    self.output_base =  self.src + "\\com\\"+self.project
    uri = 'sqlite:///data02.dm1'
    self.md = model.Model(uri)
  
    self.mdb = mapmysql.MapMysql()
    
    # table dictionary
    self.tables = self.md.getTables()
    
    #exit(0)
    self.stdout = stdout.Stdout()    
    print("init... ")
    self.start = time.time()
    #print self.start
    # create dir tree
    self.mc = mc.MC()    
    #self.mc.main()
    
  def setTables(self, tables):
      self.tables = tables

  def code(self, table, part):
    pass
  
  def actionCode(self, table):
    Table = self.getCap(table)
    sqloutput = open(self.output_base+"\\module\\"+table.replace("_","") +"\\action\\"+Table+"Action.java", 'w') 
    Table = self.getCap(table)
    nameSpace = {'table':table, 'Table':Table}     
    sp = Template(file="mod_template\\action\\Action.java", searchList=[nameSpace])
    sp = "%s"%(sp)
    sqloutput.writelines(sp)

  def hibernatecfg(self):
    tables = []
    print self.tables
    for table in self.tables:
      tab = {}
      tab['table'] =   table[0:-1]  #remove s
      tab['tablep'] =  table[0:-1].lower()  #remove s
      tab['type'] =  self.tables[table]      
      tab['cname'] = table.replace("_","")[0:-1] #remove s
      tab['Table'] = self.getCap(table)[0:-1] #remove s
      tables.append(tab)
    
    configs = ['hibernate.cfg.xml','web.xml','struts-config.xml']
    for cfg in configs:
      op = cfg.replace('.xml','')
      if self.genoptdict[op] == 'yes':
        print "gen: "+op
        pathout = self.src + "\\" + cfg
        output = open(pathout, 'w') 
        nameSpace = {'tables':tables}
        pathin = self.pathfilter("mod_template\\conf\\"+cfg)
        sp = Template(file=pathin, searchList=[nameSpace])
        sp = "%s"%(sp)
        output.writelines(sp)
    
    
  def businessCode(self):
    pass
    
  def formCode(self):
    pass

  def getTabDict(self, table):
    tabdict = {}
    
    #table = table
    fields = self.md.getColumns(table)    
    
    #print( table, self.tables[table] ) 
    
    #print table
    type = self.tables[table]
    Table = self.getCap(table)
    PTable = [] #{}
    propertys = []
    #print self.getCap(table)
    dict = {}
    pk = ''
    for row in fields:
      #print self.getMapping(row['Type'])
      property ={}
      str = row['Field']
      
      if str.find('FK_') == 0:
        pclass = {}
        
        fkobj = self.getParentObj(str) 
        parent_table = self.getParentObj(str) + "S"
        
        #calculate the fk sequence
        if fkobj in dict:
          dict[fkobj] = dict[fkobj] + 1          
        else:
          dict[fkobj] = 1
        
        pclass['name'] = fkobj.replace("_","").lower()
        pclass['type'] = self.tables[parent_table]
        pclass['table'] = fkobj
        #pclass['cname'] = 
        pclass['class'] = self.getCap(fkobj)
        pclass['column'] = str.upper()
        #print dict[fk]
        if dict[fkobj] == 1:
          pclass['seq'] = ""
        else:
          pclass['seq'] = dict[fkobj]
        
        PTable.append(pclass)
        
      elif str.find('PK_') == 0:
        pk = str.upper()
      else:
        #print row['Field']
        property['col'] = row['Field'].upper()
        property['name'] = row['Field'].replace("_","").lower()
        property['attribute'] = row['attribute']
        property['coltype'] = row['coltype']  
        property['type'] = self.mdb.getMD(row['Type'])
        if row['Length'] == -1:
          row['Length'] = 0
        elif row['Type'] == 'TEXT':
          row['Length'] = 2000        # here define the TEXT lenght when using java.lang.String
        property['length'] = row['Length']
        property['null'] = 'null'
        propertys.append(property)
   
    jtable = table.replace("_","")[0:-1]
    
    tabdict['table'] = table[0:-1] # remove the S
    tabdict['tablep'] = table[0:-1].lower()
    tabdict['Table'] = Table[0:-1] # remove the S
    tabdict['pk'] = pk
    tabdict['PTable'] = PTable
    tabdict['propertys'] = propertys
    tabdict['jtable'] = jtable
    tabdict['type'] = type
    #print tabdict
    #print ">>>>>>>>>>>>>>>>>>>>>>>"
    #print tabdict
    #print "<<<<<<<<<<<<<<<<<<<<<<<"
    return tabdict

  def ormCode(self,tablename, type):
    #print tablename
    td = self.getTabDict(tablename)
    print td    
    if self.genoptdict['action'] == 'yes':
      comp =  "action"
      pathout = "%s\\module\\%s\\actions\\%sAction.java "%(self.output_base, type,td['Table'])
      pathin ="mod_template\\action\\Action.java"
      self.output(pathin, pathout,td, comp)
    if self.genoptdict['hbm'] == 'yes':
      comp = "hbm"
      pathout = "%s\\module\\%s\\orm\\%s.hbm.xml "%(self.output_base, type,td['Table'])
      pathin ="mod_template\\orm\\hbm.xml"
      self.output(pathin, pathout,td, comp)
    
    if self.genoptdict['struts-module'] == 'yes':
      comp = "struts-module"
      pathout = "%s\\struts-module\\struts-module-%s.xml "%(self.src, td['jtable'])
      pathin ="mod_template\\conf\\struts-module.xml"
      self.output(pathin, pathout,td, comp)
      
    if self.genoptdict['tiles-defs'] == 'yes':
      comp = "tiles-defs"
      pathout = "%s\\struts-module\\tiles-defs-%s.xml "%(self.src, td['jtable'])
      pathin ="mod_template\\conf\\tiles-defs.xml"
      self.output(pathin, pathout,td, comp)

    if self.genoptdict['pojo'] == 'yes':
      comp = "pojo"
      pathout = "%s\\module\\%s\\orm\\%s.java "%(self.output_base, type, td['Table'])
      pathin="mod_template\\orm\\module.java"
      self.output(pathin, pathout,td, comp)
      
    if self.genoptdict['dao'] == 'yes':
      comp = "dao"
      pathout = "%s\\module\\%s\\orm\\%sDAO.java "%(self.output_base, type,td['Table'])
      pathin="mod_template\\orm\\DAO.java"
      self.output(pathin, pathout,td, comp)

    if self.genoptdict['test'] == 'yes':
      comp = "test"
      pathout = "%s\\test\\Test%s.java"%(self.output_base,td['Table'])
      pathin="mod_template\\test\\Test.java"
      self.output(pathin, pathout,td, comp)

    if self.genoptdict['form'] == 'yes':
      comp = "form"
      pathout = self.output_base+"\\module\\" + type + "\\forms\\"+td['Table']+"Form.java"
      pathin="mod_template\\form\\Form.java"
      self.output(pathin, pathout,td, comp)

    if self.genoptdict['business'] == 'yes':
      comp = "business"
      pathout = self.output_base+"\\module\\" + type + "\\business\\"+td['Table']+"Blogic.java"
      pathin ="mod_template\\business\\Business.java"
      self.output(pathin, pathout,td, comp)
    
    if self.genoptdict['jsp'] == 'yes':
      comp = "jsp"
      pathout = self.jsp+"\\module\\" + type + "\\" + td['Table']+".jsp"
      pathin ="mod_template\\jsp\\jsp.jsp"
      self.output(pathin, pathout,td, comp)
    
    print( "\n>>>>>") 

  def pathfilter(self, pathin):
    pathes= pathin.split("\\")
    pathin = "%s\\java\\%s\\%s" %(pathes[0], pathes[1], pathes[2])
    return pathin
    
  def output(self,pathin, pathout,tabdict, component):
    #print component,]
    #pathout = pathout.lower()
    print pathin
    basedir = os.path.dirname(pathout).lower()
    pathin = self.pathfilter(pathin)
    #print basedir
    #print pathin
    #print pathout
    #print tabdict
    #print component
    
    self.mc.mkdir(basedir)
    output = open(pathout, 'w') 
    nameSpace = {'tabdict':tabdict}     
  
    sp = Template(file=pathin, searchList=[nameSpace])
    
    sp = "%s"%(sp)
    sp = sp.encode('utf8')
    output.writelines(sp)
    
    
  def getCap(self, word):
    
    wordlist = word.split('_')
    #print wordlist,
    if 1 == len(wordlist):
      return word.capitalize()
    else:
      y = ""
      for x in wordlist:
        y += x.capitalize()
      return y
      
    #return cap
  
  
  def getParentObj(self, word):
    #print word
    wordlist = word.split('_')
    y = ""
    for x in range(1,len(wordlist)-1):
      y  += wordlist[x]+'_'
    return y.strip('_')
  

    

    
  def run(self):
    
    #generate hibernate configure file
    self.hibernatecfg()
    
    src =  self.project_path + "\\src\\com\\kylin"
    self.mc.mcopy("mod_template\\resources\\*.*", self.project_path)
    
    #print self.tables
    
    
    for tab in self.tables:
      type = self.tables[tab]
      print "type: " +type
      self.ormCode(tab,type)
    
    
    
    #self.hbmgen()
    #self.stdout.redirect(self.stdout.getOld())
    print("\ndone!")
    print("please check dir: [%s]\n" %(self.project_path))
  
  def hbmgen(self):
    comp =  "action"
    
    
    pathin ="mod_template\\action\\Action.java"
    pathin = self.pathfilter(pathin)
    hbm = Template(file=pathin)
    
    for tab in self.tables:
      td = self.getTabDict(tab) 
      type = self.tables[tab]
      #pathout = "%s\\%s\\%s\\action\\%s.java "%(self.output_base, type,td['jtable'],td['Table'])  
      hbm.tabdict = td
      #print hbm
    
    
    
  def __del__(self):
    end = time.time()
    #print end
    print "%4.2f" %(end-self.start)
    pass
    #input.close()

def main():
    d = CodeGen()
    d.run()

if __name__ == "__main__":
  main()
  """
  import profile
  profile.run('main()','gen.txt')
  import pstats
  p = pstats.Stats("gen.txt")
  p.sort_stats("time").print_stats()
  """
